package ws.very.util.lang

import scala.reflect.ClassTag
import ShortTypes._
object PfnProxy extends FnCookies {

  def wrap[F, F2, T, T2](warpPfn: PFn[F2, T])(implicit newApply: (F2, => T) => T2, caseConvert: Case[F, F2]): PFn[F, T2] =
    {
      case caseConvert(result) if (warpPfn.isDefinedAt(result)) => newApply(result, warpPfn(result))
    }

  def aop[F:ClassTag,T,T2](oldPfn: PFn[F, T])(newApply: (F, => T) => T2)=
    wrap(oldPfn)(newApply,{ f: F => Some(f) })

  /**
   * 与andThen相比
   * andThen{r=>}//这里是个非函数 不能用于try{r}
   */
  def apply[F: ClassTag, T, T2](oldPfn: PFn[F, T])(newApply: (=> T) => T2): PFn[F, T2] = wrap(oldPfn)(newApply = {
    case (f2, fn) =>
      newApply(fn)
  }, caseConvert = { f: F => Some(f) })

}